package com.katze.common.http;

import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.Enumeration;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
 * 说  明：发送请求
 * params：为Json格式时，需要在接口中添加 @RequestBody 标签，
 * 在常规情况下该参数默认为空，所有参数以符号&拼接一起追加到URL后面，例如：http://ip:port/content?userId=1&usernmae=admin
 * 作  者：zf.zeng
 * 日  期：2020-12-01 (星期二)
 **/
public class Requester extends BaseRequester {

    // request headers
    public static final String HEADER_TOKEN_NAME = "Authentication";
    public static final String HEADER_SOCKET_TOKEN_NAME = "Sec-WebSocket-Protocol";
    public static final String HEADER_ACCOUNT_NAME_KEY = "Account";

    private static Requester requester = null;

    public synchronized static Requester getInstance() {
        if (requester == null) {
            requester = new Requester();
        }
        return requester;
    }

    public synchronized static Requester getInstance(String token) {
        if (requester == null) {
            requester = new Requester();
        }
        requester.addHeader(item -> item.put(HEADER_TOKEN_NAME, token));
        return requester;
    }

    public Requester init(String uri, String... params) {
        requester.setUri(uri);
        if (params.length == 1) requester.setParams(params[0]);
        return this;
    }

    public Requester header(String key, String value) {
        requester.addHeader(item -> item.put(key, value));
        return this;
    }

    public Requester header(HttpServletRequest request) {
        Enumeration<String> headNames = request.getHeaderNames();
        while (headNames.hasMoreElements()) {
            String headName = headNames.nextElement();
            requester.addHeader(item -> item.put(headName, request.getHeader(headName)));
        }
        return this;
    }

    public Requester headers(Map<String, String> headers) {
        requester.addHeader(item -> item.putAll(headers));
        return this;
    }

    @Override
    public String sendRequest(RequestMethod method) throws IOException {
        HttpURLConnection conn = null;
        String result;
        try {
            conn = super.getConnection(method);
            result = super.reader(conn.getResponseCode() == HttpURLConnection.HTTP_OK? conn.getInputStream():conn.getErrorStream());
        } finally {
            if (conn != null) conn.disconnect();
        }
        return result;
    }

    @Override
    public void sendRequest(Consumer<InputStream> consumer, RequestMethod method) throws IOException {
        HttpURLConnection conn = null;
        try {
            conn = super.getConnection(method);
            consumer.accept(conn.getResponseCode() == HttpURLConnection.HTTP_OK? conn.getInputStream():conn.getErrorStream());
        } finally {
            if (conn != null) conn.disconnect();
        }
    }

    @Override
    public void sendRequest(BiConsumer<HttpURLConnection, InputStream> consumer, RequestMethod method) throws IOException {
        HttpURLConnection conn = null;
        try {
            conn = super.getConnection(method);
            consumer.accept(conn, conn.getResponseCode() == HttpURLConnection.HTTP_OK?conn.getInputStream():conn.getErrorStream());
        } finally {
            if (conn != null) conn.disconnect();
        }
    }
}
